import type {MessageApiInjection} from "naive-ui/es/message/src/MessageProvider";
import type {DialogApiInjection} from "naive-ui/es/dialog/src/DialogProvider";
import post from "../axios";

export let getObj2ValueArrayWhileObj1HasSameKey = (obj1: any, obj2: any) => {
    let array: Array<any> = []
    Object.entries(obj1).forEach(([key1, value1]) => {
        if (value1) {
            Object.entries(obj2).forEach(([key2, value2]) => {
                if (key1 === key2) {
                    array.push(value2)
                }
            })
        }
    })
    return array
}

export let confirm = (msg: string, ok: Function, cancel?: Function) => {
    util.dialog?.warning({
        title: '警告',
        content: msg,
        positiveText: '确定',
        negativeText: '取消',
        onPositiveClick: () => {
            ok()
        },
        onNegativeClick: () => {
            cancel?.()
        }
    })
}

export let replace = <I>(source: I, target: any): I => {
    if (source == null) {
        return source
    }
    if (target == null) {
        return source
    }
    const keys1 = Reflect.ownKeys(source) as string[];
    const keys2 = Reflect.ownKeys(target) as string[];
    if (keys2.length == 0) {
        return source
    }
    for (const key1 of keys1) {
        for (const key2 of keys2) {
            if (key1 === key2) {
                let value1 = Reflect.get(source, key1)
                let value2 = Reflect.get(target, key2)
                if (value2 == null) {
                    continue
                }
                if (value1 == null) {
                    Reflect.set(source, key1, value2)
                    continue
                }
                if (value1 instanceof Array && value2 instanceof Array) {
                    let arr: Array<any> = value1
                    value2.forEach((item: any, index: number) => {
                        if (index < arr.length) {
                            arr[index] = replace(arr[index], item)
                        }
                    })
                    while (value1.length < value2.length) {
                        value1.push(value2[value1.length])
                    }
                } else if (typeof value1 === 'object') {
                    replace(value1, value2)
                } else {
                    Reflect.set(source, key1, value2)
                }
            }
        }
    }
    for (const key2 of keys2) {
        if (keys1.includes(key2)) {
            continue
        }
        let value2 = Reflect.get(target, key2)
        Reflect.set(source, key2, value2)
    }

    return source
}

export let stampToDateText = (stamp: number) => {
    let date = new Date(stamp)
    return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate()
}

export let stampToDatetimeText = (stamp: number) => {
    let date = new Date(stamp)
    return date.getFullYear() + '-'
        + (date.getMonth() + 1) + '-' + date.getDate() + ' '
        + (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
        + (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'
        + (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds())
}

export let util: {
    msg: MessageApiInjection | null,
    dialog: DialogApiInjection | null,
    confirm: Function,
    loadOptions: Function
} = {
    msg: null,
    dialog: null,
    confirm: confirm,
    loadOptions: (key: string, option: Option) => {
        if (options.has(key)) {
            option.callback(options.get(key)?.data)
        } else {
            post(option.utl, option.param).then((res: any) => {
                option.data = res
                option.callback(option.data)
            })
        }
    }
}

let options = new Map<String, Option>

interface Option {
    utl: string
    param: any
    data: Array<{ value: string | number, label: string }>
    callback: Function
}